﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace BizElements.Generator
{
    static class ReflectionUtil
    {
        public static Assembly LoadAssembly(string filePath)
        {
            // Temporary switch directory.
            string oldCwd = Directory.GetCurrentDirectory();
            string oldAsmDir = AppMain.AsmDependenciesDirectory;
            try
            {
                string tempCwd = Path.GetDirectoryName(filePath);
                Directory.SetCurrentDirectory(tempCwd);
                AppMain.AsmDependenciesDirectory = tempCwd;

                Assembly asm = Assembly.LoadFile(filePath);
                // GetType will force loading of all referenced assemblies - asm.GetReferencedAssemblies().
                asm.GetTypes();
                return asm;
            }
            finally
            {
                Directory.SetCurrentDirectory(oldCwd);
                AppMain.AsmDependenciesDirectory = oldAsmDir;
            }
        }

        public static object CreateObjectLocatedIn3rdPartyAssembly(Assembly asm, string fullTypeName)
        {
            // Temporary switch directory.
            string oldCwd = Directory.GetCurrentDirectory();
            string oldAsmDir = AppMain.AsmDependenciesDirectory;
            string filePath = asm.Location;
            try
            {
                string tempCwd = Path.GetDirectoryName(filePath);
                Directory.SetCurrentDirectory(tempCwd);
                AppMain.AsmDependenciesDirectory = tempCwd;

                var ctor = asm.GetType(fullTypeName).GetConstructor(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, new Type[0], new ParameterModifier[0]);
                if (ctor == null)
                    throw new InvalidOperationException(string.Format(Messages.DotNetProjecGenerator_TypeXDoesntHaveDefaultCtor, fullTypeName));

                return ctor.Invoke(null);
            }
            finally
            {
                Directory.SetCurrentDirectory(oldCwd);
                AppMain.AsmDependenciesDirectory = oldAsmDir;
            }
        }
    }
}
